from flask import g, redirect, render_template, abort, request, jsonify, current_app

from info import db
from info.constants import QINIU_DOMIN_PREFIX, USER_COLLECTION_MAX_NEWS
from info.models import Category, News, tb_user_collection, User
from info.modules.user import user_blu
from info.utils.common import user_login_data


# 显示个人中心
from info.utils.img_storage import upload_img
from info.utils.response_code import error_map, RET


@user_blu.route('/user_info')
@user_login_data
def user_info():

    # 判断用户是否登录
    user = g.user
    if not user:
        return redirect("/")

    return render_template("news/user.html", user=user)


# 获取/修改基本信息
@user_blu.route('/base_info', methods=['POST', 'GET'])
@user_login_data
def base_info():
    user = g.user
    if not user:
        abort(404)

    if request.method == "GET":
        return render_template("news/user_base_info.html", user=user.to_dict())
    # 不是GET,就是修改数据
    # 获取参数
    signature = request.json.get("signature")
    nick_name = request.json.get("nick_name")
    gender = request.json.get("gender")
    # 校验参数
    if not all([signature, nick_name, gender]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    if gender not in ["MAN", "WOMAN"]:
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 修改用户模型的数据
    user.signature = signature
    user.nick_name = nick_name
    user.gender = gender

    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 获取/上传头像
@user_blu.route('/pic_info', methods=['POST', 'GET'])
@user_login_data
def pic_info():
    user = g.user
    if not user:
        abort(404)

    if request.method == "GET":
        return render_template("news/user_pic_info.html", user=user.to_dict())
    # 不是GET,就是修改数据
    try:
        img_bytes = request.files.get("avatar").read()
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])

    # 上传文件  云存储平台   压缩方式优化, 传输宽带高, 数据去重
    try:
        key = upload_img(img_bytes)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg=error_map[RET.THIRDERR])

    # 将文件的访问url返回给前端
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK], data={"avatar_url": QINIU_DOMIN_PREFIX + key})


# 获取/修改密码
@user_blu.route('/pass_info', methods=['POST', 'GET'])
@user_login_data
def pass_info():
    user = g.user
    if not user:
        abort(404)

    if request.method == "GET":
        return render_template("news/user_pass_info.html")
    # 不是GET,就是修改数据
    old_password = request.json.get("old_password")
    new_password = request.json.get("new_password")
    if not all([old_password, new_password]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    
    # 校验旧密码
    if not user.check_password(old_password):
        return jsonify(errno=RET.PWDERR, errmsg=error_map[RET.PWDERR])
    
    # 修改密码
    user.password = new_password
    
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])


# 显示收藏的新闻
@user_blu.route('/collection')
@user_login_data
def collection():
    user = g.user
    if not user:
        abort(404)

    # 获取参数
    page = request.args.get("p", 1)
    try:
        page = int(page)
    except BaseException as e:
        current_app.logger.error(e)
        page = 1

    # 查询该用户收藏的新闻
    news_list = []
    total_pages = 1
    try:
        # pn = user.collection_news.paginate(page, USER_COLLECTION_MAX_NEWS)
        # news_list = [news.to_dict() for news in pn.items]
        # total_pages = pn.pages

        pn = user.collection_news.order_by(tb_user_collection.c.create_time.desc()).paginate(page,
                                                                                             USER_COLLECTION_MAX_NEWS)
        for news in pn.items:
            news_dict = news.to_dict()
            # 查询新闻收藏时间
            from sqlalchemy import and_
            sql = and_(
                tb_user_collection.c.user_id == user.id,
                tb_user_collection.c.news_id == news.id)

            s = db.select([tb_user_collection.c.create_time]).where(sql)

            news_collect_time = db.engine.execute(s).fetchall()[0][0].strftime('%Y-%m-%d')
            news_dict["news_collect_time"] = news_collect_time
            news_list.append(news_dict)

    except BaseException as e:
        current_app.logger.error(e)

    data = {
        "total_page": total_pages,
        "news_list": news_list,
        "cur_page": page
    }

    return render_template("news/user_collection.html", data=data)


# 发布新闻
@user_blu.route('/news_release', methods=['POST', 'GET'])
@user_login_data
def news_release():
    user = g.user
    if not user:
        abort(404)

    if request.method == "GET":
        # 查询分类
        categories = []
        try:
            categories = Category.query.all()
        except BaseException as e:
            current_app.logger.error(e)

        if len(categories):
            categories.pop(0)
        return render_template("news/user_news_release.html", categories=categories)
    # 不是GET,就是修改数据
    # 获取数据
    title = request.form.get("title")
    category_id = request.form.get("category_id")
    digest = request.form.get("digest")
    index_img_file = request.files.get("index_image")
    content = request.form.get("content")
    if not all([title, category_id, digest, index_img_file, content]):
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    try:
        category_id = int(category_id)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    
    # 上传文件
    try:
        inde_img_bytes = index_img_file.read()
        key = upload_img(inde_img_bytes)
    except BaseException as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR, errmsg=error_map[RET.PARAMERR])
    
    # 创建新闻模型
    news = News()
    news.title = title
    news.category_id = category_id
    news.digest = digest
    news.index_image_url = QINIU_DOMIN_PREFIX + key
    news.content = content
    news.user_id = user.id
    news.source = "个人发布"
    # 设置发布状态
    news.status = 1
    
    db.session.add(news)
    return jsonify(errno=RET.OK, errmsg=error_map[RET.OK])
    
    
# 显示发布的新闻
@user_blu.route('/news_list')
@user_login_data
def news_list():
    user = g.user
    if not user:
        abort(404)

    # 获取参数
    page = request.args.get("p", 1)
    try:
        page = int(page)
    except BaseException as e:
        current_app.logger.error(e)
        page = 1

    # 查询该用户发布的新闻
    news_list = []
    total_pages = 1
    try:
        pn = News.query.filter(News.user_id == user.id).paginate(page, USER_COLLECTION_MAX_NEWS)
        news_list = [news.to_review_dict() for news in pn.items]
        total_pages = pn.pages
    except BaseException as e:
        current_app.logger.error(e)

    data = {
        "total_page": total_pages,
        "news_list": news_list,
        "cur_page": page
    }

    return render_template("news/user_news_list.html", data=data)
    
    
# 显示关注列表
@user_blu.route('/user_follow')
@user_login_data
def user_follow():
    user = g.user
    if not user:
        abort(404)

    # 获取参数
    page = request.args.get("p", 1)
    try:
        page = int(page)
    except BaseException as e:
        current_app.logger.error(e)
        page = 1

    # 查询该用户关注的人
    user_list = []
    total_pages = 1
    try:
        pn = user.followed.paginate(page, USER_COLLECTION_MAX_NEWS)
        user_list = [user.to_dict() for user in pn.items]
        total_pages = pn.pages
    except BaseException as e:
        current_app.logger.error(e)

    data = {
        "total_page": total_pages,
        "user_list": user_list,
        "cur_page": page
    }

    return render_template("news/user_follow.html", data=data)

# 显示个人主页
@user_blu.route('/other')
@user_login_data
def other():
    # 获取参数
    user_id = request.args.get("user_id")
    try:
        user_id = int(user_id)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(404)

    try:
        author = User.query.get(user_id)
    except BaseException as e:
        current_app.logger.error(e)
        return abort(404)

    if not author:
        return abort(404)

    user = g.user

    is_followed = False
    # 登录状态
    if user :
        # 判断当前用户是否关注了这个作者
        if author in user.followed:
            is_followed = True


    # 获取参数
    page = request.args.get("p", 1)
    try:
        page = int(page)
    except BaseException as e:
        current_app.logger.error(e)
        page = 1

    # 查询该用户发布的新闻
    news_list = []
    total_pages = 1
    try:
        pn = News.query.filter(News.user_id == author.id, News.status == 0).paginate(page, USER_COLLECTION_MAX_NEWS)
        news_list = [news.to_review_dict() for news in pn.items]
        total_pages = pn.pages
    except BaseException as e:
        current_app.logger.error(e)

    data = {
        "total_page": total_pages,
        "news_list": news_list,
        "cur_page": page
    }
    user = user.to_dict() if user else None

    return render_template("news/other.html", author=author.to_dict(), user=user, is_followed=is_followed, data=data)

